<template>
	<view class="container">
		<!-- 用于关联renderjs的特殊view -->
		<view :url="signalR_baseUrl" :change:url="signalR.getBaseUrl" :userid="signalR_userid"
			:change:userid="signalR.getUserId" :appstatus="AppStatus" :change:appstatus="signalR.changeAppStatus">
		</view>

		<Lock></Lock>

		<Header ref="header" class="header" @confirmSearch="doSearch"></Header>

		<view class="catalogContainer">
			<view class="catalogType">
				<view class="catalogType-item" :class="{selected:catalogType==1}" @click="selectCatalogType(1)">
					知识点
				</view>
				<view class="catalogType-item" :class="{selected:catalogType==2}" @click="selectCatalogType(2)">
					专题库
				</view>
				<view class="catalogType-item" :class="{selected:catalogType==4}" @click="selectCatalogType(4)">
					随堂测试
				</view>
			</view>
			<view v-if="catalogType==1||catalogType==2" class="catalogs">
				<CatalogTree :key="catalogType" :catalogTree="catalogTrees[catalogType]"
					:activeCatalogId="activeCatalogId" @chooseCatalog="chooseCatalog"></CatalogTree>
			</view>
		</view>

		<view class="mainContainer">
			<view class="tabList">
				<view class="tab" :class="{active:tabIndex==0}" @click="changeTabIndex(0)">试卷一览</view>
				<view class="tab" :class="{active:tabIndex==1}" @click="changeTabIndex(1)">我的作品</view>
			</view>
			<view class="tableContainer">
				<view class="table-list">
					<view v-for="item of tableList" class="table-item" @click="goDetail(item)">
						<template v-if="tabIndex==0">
							<view class="table-line">
								<view class="title">{{item.paperTitle}}</view>
								<view class="btns">
									<view v-if="item.hasRecord" @click.stop="toggleRecords(item)">
										答题记录
										<uni-icons v-if="item.records.length" type="top" size="1vw"></uni-icons>
										<uni-icons v-else type="forward" size="1vw"></uni-icons>
									</view>
								</view>
							</view>
							<view v-show="item.records.length" class="records">
								<view v-for="record of item.records" class="record" @click.stop="goRecord(record)">
									<text class="creationTime">{{record.creationTime.slice(0,10)}}</text>
									<text>得分：{{record.recordScore}}分</text>
								</view>
							</view>
						</template>
						<template v-if="tabIndex==1">
							<view class="table-line">
								<view class="title">
									{{item.taskPaper.paperTitle}}
								</view>
								<view class="btns">
									得分：{{item.recordScore}}
									<text class="creationTime">{{item.creationTime.slice(0,10)}}</text>
								</view>
							</view>
						</template>
					</view>
				</view>

				<Pagination :paperList="paperList" :pageIndex="pageIndex" :itemPerPage="itemPerPage"
					@changePageIndex="pageIndex=$event"></Pagination>

			</view>
		</view>


	</view>
</template>

<script>
	import Lock from "@/components/Lock";
	import Header from "./components/Header";
	import CatalogTree from "@/components/CatalogTree";
	import Pagination from "./components/Pagination.vue";

	export default {
		components: {
			Lock,
			Header,
			CatalogTree,
			Pagination
		},
		data() {
			return {
				activeCatalogId: null,
				catalogType: 1, //1知识点 //2专题库 //4随堂测试
				catalogTrees: {
					1: [],
					2: [],
				},
				tabIndex: 0, //0所有试卷 1作品集

				//列表
				paperList: [],
				pageIndex: 1,
				itemPerPage: 20,

			}
		},
		computed: {
			tableList() {
				return this.paperList.slice((this.pageIndex - 1) * this.itemPerPage, this.pageIndex * this.itemPerPage)
			},
			signalR_baseUrl() {
				return this.$store.state.appConfig.baseURL
			},
			signalR_userid() {
				return this.$store.state.session.userId
			},
			AppStatus() {
				return this.$store.state.AppStatus
			}

		},
		mounted() {
			this.getCatalogs();
			this.getList();
			// #ifdef H5
			window.callJsFunction = this.goDetail;
			// #endif

			//测试分页
			// let res = [];
			// for (let i = 0; i < 505; i++) {
			// 	res.push({
			// 		paperTitle: "一个长长试卷" + i,
			// 		hasRecord: i % 2 ? true : false
			// 	})
			// }
			// this.paperList = res;
		},
		activated() {},
		deactivated() {},
		beforeDestroy() {},
		methods: {
			getCatalogs() {
				this.axios.get("/api/services/app/Task/GetCatalogs").then(res => {
					this.catalogTrees = {
						1: this.arrayToTree(res.filter(item => item.catalogType == 1).map(item => ({
							id: item.id,
							name: item.name,
							parentId: item.parentId
						})), '00000000-0000-0000-0000-000000000000'),
						2: this.arrayToTree(res.filter(item => item.catalogType == 2).map(item => ({
							id: item.id,
							name: item.name,
							parentId: item.parentId
						})), '00000000-0000-0000-0000-000000000000'),
					}
				})
			},
			arrayToTree(data, pid) {
				let result = [];
				for (const item of data) {
					if (item.parentId === pid) {
						const newItem = {
							children: this.arrayToTree(data, item.id),
							...item
						}
						result.push(newItem)
					}
				}
				return result;
			},
			selectCatalogType(catalogType) {
				this.catalogType = catalogType;
				if (catalogType == 1 || catalogType == 2) {
					this.getCatalogs();
				}

				this.activeCatalogId = null;
				this.$refs.header.searchText = "";

				this.getList();
			},
			chooseCatalog(item) {
				//最终子节点
				this.activeCatalogId = item.id;
				this.$refs.header.searchText = ""; //选分类则清空搜索
				this.getList();
			},
			doSearch() {
				this.activeCatalogId = null; //选搜索则清空分类
				this.getList();
			},
			getList() {
				this.paperList = [];

				if (this.tabIndex == 0) {
					if (this.activeCatalogId) {
						this.getTaskPapers()
					} else {
						this.getTaskPapersByCategoryId()
					}
				} else if (this.tabIndex == 1) {
					if (this.activeCatalogId) {
						this.getTaskPaperRecords()
					} else {
						this.getTaskPaperRecordsByCategoryId()
					}
				}
			},
			getTaskPapers() {
				this.axios.get("/api/services/app/Task/GetTaskPapers", {
					params: {
						catalogId: this.activeCatalogId
					}
				}).then(res => {
					console.log("res", res)
					this.paperList = res.map(item => {
						return {
							...item,
							records: []
						}
					});
				})
			},
			getTaskPapersByCategoryId() {
				this.axios.get("/api/services/app/Task/GetTaskPapersByCategoryId", {
					params: {
						catalogType: this.catalogType,
						query: this.$refs.header.searchText
					}
				}).then(res => {
					console.log("res", res)
					this.paperList = res.map(item => {
						return {
							...item,
							records: []
						}
					});
				})
			},
			getTaskPaperRecords() {
				this.axios.get("/api/services/app/Task/GetTaskPaperRecords", {
					params: {
						catalogId: this.activeCatalogId
					}
				}).then(res => {
					console.log("res", res)
					this.paperList = res;
				})
			},
			getTaskPaperRecordsByCategoryId() {
				this.axios.get("/api/services/app/Task/GetTaskPaperRecordsByCategoryId", {
					params: {
						catalogType: this.catalogType,
						query: this.$refs.header.searchText
					}
				}).then(res => {
					console.log("res", res)
					this.paperList = res;
				})
			},
			changeTabIndex(index) {
				this.tabIndex = index;
				this.getList();
			},
			goDetail(item) {
				console.log("goDetail", item)
				//随堂测试只能做一次
				if (this.catalogType == 4 && item.hasRecord) return;
				if (this.tabIndex == 0) {
					uni.navigateTo({
						url: `/pages/paper/paper?id=${item.id}`
					})
				} else if (this.tabIndex == 1) {
					uni.navigateTo({
						url: `/pages/paper/paper?id=${item.taskPaper.id}&recordId=${item.id}`
					})
				}
			},
			toggleRecords(paper) {
				if (paper.records.length) {
					paper.records.splice(0)
				} else {
					this.axios.get("/api/services/app/Task/GetTaskPaperRecords", {
						params: {
							taskPaperId: paper.id,
						}
					}).then(res => {
						paper.records = res;
					})
				}
			},
			goRecord(record) {
				uni.navigateTo({
					url: `/pages/paper/paper?id=${record.taskPaper.id}&recordId=${record.id}`
				})
			},


			//signalR
			reciveMsg(msg) {
				//由renderjs中的this.$ownerInstance.callMethod调用
				console.log("signalR reciveMsg:", msg);
				let data;
				try {
					data = JSON.parse(msg);
				} catch (e) {
					data = msg;
				}
				//新的随堂测试
				if (data.type == 1) {
					uni.showModal({
						title: '提示',
						content: `收到新的随堂测试《${data.paperTitle}》，是否立即进入答题？`,
						success: (res) => {
							if (res.confirm) {
								uni.navigateTo({
									url: `/pages/paper/paper?id=${data.id}`,
								})
							}
						}
					});
				}
				//教师锁屏（全局锁）
				else if (data.type == 2) {
					this.$store.commit("setClassLock", 1)
				} 
				//教师锁屏（但保留本APP活动）
				else if (data.type == 5) {
					this.$store.commit("setClassLock", 2)
				}
				//结束锁屏
				else if (data.type == 3) {
					this.$store.commit("setClassLock", false)
				}
				//随堂测试收卷
				else if (data.type == 4 && data.id && data.id != "00000000-0000-0000-0000-000000000000") {
					const currentPages = getCurrentPages();
					const currentPage = currentPages[currentPages.length - 1];
					// console.log("CurrentPage", currentPage)
					// console.log("CurrentPage.__page__", currentPage.__page__)
					const targetUrl = `/pages/paper/paper?id=${data.id}&forceSubmit=1`;
					//本来就在该试卷界面
					if (currentPage.__page__ && currentPage.__page__.route == "pages/paper/paper" &&
						currentPage.__page__.options.id == data.id) {
						//立刻缓存当前结果并跳转
						currentPage.setStorage();
						uni.redirectTo({
							url: targetUrl
						})
					}
					//在其他界面
					else {
						uni.navigateTo({
							url: targetUrl
						})
					}
				}
			},
		}
	}
</script>

<!-- signalr只能通过renderjs来调用 -->
<script module="signalR" lang="renderjs">
	import * as signalR from "@microsoft/signalr"
	let connection;
	export default {
		data() {
			return {
				baseUrl: null,
				userId: null,
				timer_start: null,
			}
		},
		methods: {
			getBaseUrl(newValue) {
				this.baseUrl = newValue;
			},
			getUserId(newValue) {
				this.userId = newValue;
			},
			changeAppStatus(newVal) {
				console.log("changeAppStatus", newVal)
				if (newVal) {
					this.start();
				}
			},
			async start() {
				console.log("SignalR start handler")
				try {
					if (connection.state == "Disconnected") {
						await connection.start();
						console.log("SignalR Connected.", connection.state);
					}
					await connection.invoke("SendMessage", this.userId)
				} catch (err) {
					//启动失败则过5秒再启动
					console.log(err);
					clearTimeout(this.timer_start);
					this.timer_start = setTimeout(this.start, 5000);
				}
			},
		},
		async mounted() {
			//url 后端SignalR的地址
			this.url = this.url + '/Hubs/Notifier';

			const retryPolicy = {
				nextRetryDelayInMilliseconds: retryContext => {
					// previousRetryCount elapsedMilliseconds retryReason
					//10秒以内每2秒重连一次
					if (retryContext.elapsedMilliseconds < 10 * 1000) {
						return 2 * 1000;
					}
					//之后每10秒重连一次
					else {
						return 10 * 1000;
					}
					// 超过十分钟放弃重连
					// else {
					// 	return null;
					// }

				}
			};

			connection = new signalR.HubConnectionBuilder()
				.withUrl(`${this.baseUrl}/messagebus`)
				.configureLogging(signalR.LogLevel.Information)
				.withAutomaticReconnect(retryPolicy)
				.build()
			//监听 ReceiveMessage 事件,名称为invoke调用后端方法后,后端返回的事件名
			await connection.on("broadcast", msg => {
				//调用<script> 也叫service层的 reciveMsg 方法 msg为方法的参数
				this.$ownerInstance.callMethod("reciveMsg", msg)
			})
			await connection.onclose(error => {
				console.log("------------connection close------------")
			})
			await connection.onreconnecting(error => {
				console.log("------------connection reconnecting------------")
			})
			this.start();

			console.log("navigator.locks.request", navigator.locks.request)

			//https://ask.dcloud.net.cn/question/59961
			//尝试用WebLock解决后台JS休眠问题，无效 https://learn.microsoft.com/aspnet/core/signalr/javascript-client#bsleep 
			// var lockResolver;
			// if (navigator && navigator.locks && navigator.locks.request) {
			// 	const promise = new Promise((res) => {
			// 		lockResolver = res;
			// 	});

			// 	navigator.locks.request('unique_lock_name', {
			// 		mode: "shared"
			// 	}, () => {
			// 		return promise;
			// 	});
			// }
		},

		//render生命周期需要用async，否则无效
		async beforeDestroy() {
			clearTimeout(this.timer_start);
			connection.stop();
		}


	}
</script>

<style lang="scss" scoped>
	$headerHeight: 6vw;
	$catalogTypeWidth: 4.8vw;
	$catalogsWidth: 20vw;

	.container {
		display: flex;
		flex-wrap: wrap;
		width: 100vw;
		height: 100vh;

		.header {
			height: $headerHeight;
		}
	}


	.catalogContainer {
		height: calc(100vh - #{$headerHeight});
		display: flex;
		background-color: #F2F6F9;

		.catalogType {
			width: $catalogTypeWidth;
			height: 100%;
			display: flex;
			flex-direction: column;
			align-items: center;
			justify-content: center;
			background-color: #C8DCFF;
			box-sizing: border-box;
			padding-bottom: 5vh;

			.catalogType-item {
				width: 3.2vw;
				font-size: 1.4vw;
				font-weight: bold;
				border-radius: 0.5vw;
				color: #2380E9;

				writing-mode: vertical-lr;
				text-orientation: upright;

				padding-top: 2vw;
				letter-spacing: 1vw;
				padding-bottom: 1vw;

				display: flex;
				flex-direction: column;
				justify-content: center;

				&.selected {
					color: #fff;
					background-color: #2380E9;
				}

				&+.catalogType-item {
					margin-top: 3vh;
				}
			}
		}


		.catalogs {
			width: $catalogsWidth;
			background-color: #C8DCFF;
			overflow: auto;
			margin-left: 0.5vw;
		}
	}

	.mainContainer {
		background-color: #F1F6F9;
		flex-grow: 1;
		box-sizing: border-box;
		padding: 1.5vw 1vw;
		// display: flex;
		// flex-direction: column;

		// 方 Tab
		// .tabList {
		// 	font-size: 1.4vw;
		// 	display: flex;
		// 	border-bottom: 0.1vw solid #ddd;
		// 	background-color: #fff;
		// 	border-top-left-radius: 0.8vw;
		// 	border-top-right-radius: 0.8vw;
		// 	overflow: hidden;

		// 	.tab {
		// 		width: 50%;
		// 		height: 4vw;
		// 		line-height: 4vw;
		// 		text-align: center;

		// 		&+.tab {
		// 			border-left: 0.1vw solid #ddd;
		// 		}

		// 		&.active {
		// 			color: #fff;
		// 			background-color: #2380E9;
		// 		}
		// 	}
		// }

		.tabList {
			font-size: 1.2vw;
			font-weight: bold;
			display: flex;
			justify-content: center;

			.tab {
				width: 10vw;
				height: 3.2vw;
				line-height: 3.2vw;
				text-align: center;
				border-radius: 5vw;
				background-color: #fff;
				border: 0.1vw solid #ddd;

				&+.tab {
					margin-left: 5vw;
				}

				&.active {
					color: #2380E9;
					border-color: #2380E9;
					background-color: #EFF4FF;
				}
			}
		}

		.tableContainer {
			width: 100%;
			background-color: #fff;
			border-radius: 0.8vw;
			// padding: 1.5vw 2vw;
			box-sizing: border-box;
			flex-grow: 1;
			margin-top: 1.5vw;

			.table-list {
				box-sizing: border-box;
				height: calc(100vh - #{$headerHeight} - 13vw);
				overflow: auto;
				padding: 1.5vw 2vw;

				.table-item {
					border: 0.1vw solid #ddd;
					font-size: 1.2vw;
					border-radius: 0.4vw;
					box-sizing: border-box;
					padding: 0 1vw;

					&+.table-item {
						margin-top: 1vw;
					}

					.table-line {
						display: flex;
						justify-content: space-between;
						height: 3vw;
						line-height: 3vw;

						.title {
							max-width: 50vw;
							overflow: hidden;
							text-overflow: ellipsis;
							white-space: nowrap;

						}

						.btns {
							display: flex;
							align-items: center;

							.creationTime {
								margin-left: 1.5vw;
								color: #999;
							}
						}


					}

					.records {
						.record {
							display: flex;
							justify-content: space-between;
							padding: 0.6vw 0;
							margin-left: 2vw;
							margin-right: 0.5vw;
							border-top: 1px solid #dcdcdc;

							.creationTime {
								margin-right: 1vw;
							}
						}
					}


				}
			}

		}
	}
</style>